package com.ziven.common.widget.title;

import android.app.Activity;
import android.content.Context;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.ziven.common.widget.value.NullValue;
import com.ziven.common.widget.value.Value;
import com.ziven.easygo.util.Nulls;

/**
 * @author Ziven
 */
public interface BaseEffect<T extends View> {

    /**
     * Init Value
     */
    default void initEffect() {
        initEffect(NullValue.VALUE);
    }

    /**
     * Init Value
     * @param value Value
     */
    default void initEffect(@NonNull Value value) {
        takeEffect(obtainValue());
        takeEffect(value);
    }

    /**
     * Take Effect Value
     * @param value Value
     */
    default void takeEffect(@NonNull Value value) {
        takeEffect(value, obtainEffectView());
    }

    /**
     * Take Effect Value
     * @param value Value
     * @param view Effect View
     */
    default void takeEffect(@NonNull Value value, @Nullable View view) {
        value.takeEffect(view);
    }

    /**
     * Activity Finish
     * @return Runnable
     */
    @NonNull
    default Runnable obtainActivityFinish() {
        return () -> obtainActivityNulls().doNotNull(Activity::finish);
    }

    /**
     * Activity Back
     * @return Runnable
     */
    @NonNull
    default Runnable obtainActivityBack() {
        return () -> obtainActivityNulls().doNotNull(Activity::onBackPressed);
    }

    /**
     * Obtain Activity Nulls
     * @return Nulls
     */
    default Nulls<Activity> obtainActivityNulls() {
        return Nulls.of(obtainActivity());
    }

    /**
     * Obtain Activity
     * @return Activity
     */
    @Nullable
    default Activity obtainActivity() {
        if(this instanceof Activity) {
            return (Activity) this;
        }

        if(this instanceof Fragment) {
            return ((Fragment) this).getActivity();
        }

        View view = this instanceof View
                ? (View) this
                : obtainEffectView();
        Context context = view.getContext();
        if(context instanceof Activity) {
            return (Activity) context;
        }

        return null;
    }

    /**
     * Obtain Value
     * @return Value
     */
    @NonNull
    Value obtainValue();

    /**
     * Obtain View
     * @return Take Effect View
     */
    @NonNull
    T obtainEffectView();
}
